<!DOCTYPE html>



  


<html class="theme-next gemini use-motion" lang="zh-Hans">
<head><meta name="generator" content="Hexo 3.8.0">
  <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="theme-color" content="#222">



  
  
    
    
  <script src="/lib/pace/pace.min.js?v=1.0.2"></script>
  <link href="/lib/pace/pace-theme-flash.min.css?v=1.0.2" rel="stylesheet">




  
  
  <link rel="stylesheet" media="all" href="/lib/Han/dist/han.min.css?v=3.3">




<meta http-equiv="Cache-Control" content="no-transform">
<meta http-equiv="Cache-Control" content="no-siteapp">
















  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css">







<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css">

<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="Groovy,">





  <link rel="alternate" href="/atom.xml" title="Colin's Blog" type="application/atom+xml">






<meta name="description" content="Reference: Apache GroovyThis chapter covers the syntax of the Groovy programming language. The grammar of the language derives from the Java grammar, but enhances it with specific constructs for Groo">
<meta name="keywords" content="Groovy">
<meta property="og:type" content="article">
<meta property="og:title" content="Groovy Syntax">
<meta property="og:url" content="http://duanyitao.com/2019/04/23/Groovy-Syntax/index.html">
<meta property="og:site_name" content="Colin&#39;s Blog">
<meta property="og:description" content="Reference: Apache GroovyThis chapter covers the syntax of the Groovy programming language. The grammar of the language derives from the Java grammar, but enhances it with specific constructs for Groo">
<meta property="og:locale" content="zh-Hans">
<meta property="og:updated_time" content="2019-04-23T10:21:07.570Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Groovy Syntax">
<meta name="twitter:description" content="Reference: Apache GroovyThis chapter covers the syntax of the Groovy programming language. The grammar of the language derives from the Java grammar, but enhances it with specific constructs for Groo">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Gemini',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":20,"b2t":true,"scrollpercent":true,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://duanyitao.com/2019/04/23/Groovy-Syntax/">





  <title>Groovy Syntax | Colin's Blog</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">Colin's Blog</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <h1 class="site-subtitle" itemprop="description">时间是没有声音的锉刀。</h1>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br>
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br>
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br>
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br>
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-android">
          <a href="/categories/Android/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-android"></i> <br>
            
            Android
          </a>
        </li>
      
        
        <li class="menu-item menu-item-kotlin">
          <a href="/categories/Kotlin/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-code"></i> <br>
            
            Kotlin
          </a>
        </li>
      
        
        <li class="menu-item menu-item-dart">
          <a href="/categories/Dart/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-terminal"></i> <br>
            
            Dart
          </a>
        </li>
      
        
        <li class="menu-item menu-item-flutter">
          <a href="/categories/Flutter/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-road"></i> <br>
            
            Flutter
          </a>
        </li>
      
        
        <li class="menu-item menu-item-ios">
          <a href="/categories/iOS/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-apple"></i> <br>
            
            iOS
          </a>
        </li>
      
        
        <li class="menu-item menu-item-web">
          <a href="/categories/Web/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-html5"></i> <br>
            
            Web
          </a>
        </li>
      
        
        <li class="menu-item menu-item-vim">
          <a href="/categories/Vim/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-code"></i> <br>
            
            Vim
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br>
            
            关于
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://duanyitao.com/2019/04/23/Groovy-Syntax/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="段燚涛">
      <meta itemprop="description" content>
      <meta itemprop="image" content="/images/avatar.jpeg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Colin's Blog">
    </span>

    
      <header class="post-header">

        
        
          <h2 class="post-title" itemprop="name headline">Groovy Syntax</h2>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2019-04-23T15:09:10+08:00">
                2019-04-23
              </time>
            

            
              <span class="post-meta-divider">|</span>
            

            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-check-o"></i>
              </span>
              
                <span class="post-meta-item-text">更新于&#58;</span>
              
              <time title="更新于" itemprop="dateModified" datetime="2019-04-23T18:21:07+08:00">
                2019-04-23
              </time>
            
          </span>

          
            <span class="post-category">
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Groovy/" itemprop="url" rel="index">
                    <span itemprop="name">Groovy</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          
            <div class="post-wordcount">
              
                
                <span class="post-meta-item-icon">
                  <i class="fa fa-file-word-o"></i>
                </span>
                
                  <span class="post-meta-item-text">字数统计&#58;</span>
                
                <span title="字数统计">
                  5.5k
                </span>
              

              
                <span class="post-meta-divider">|</span>
              

              
                <span class="post-meta-item-icon">
                  <i class="fa fa-clock-o"></i>
                </span>
                
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                
                <span title="阅读时长">
                  34
                </span>
              
            </div>
          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body han-init-context" itemprop="articleBody">

      
      

      
        <blockquote>
<p>Reference: <a href="http://groovy-lang.org/syntax.html" target="_blank" rel="noopener">Apache Groovy</a><br>This chapter covers the syntax of the Groovy programming language. The grammar of the language derives from the Java grammar, but enhances it with specific constructs for Groovy, and allows certain simplifications.</p>
</blockquote>
<h2 id="Comments"><a href="#Comments" class="headerlink" title="Comments"></a>Comments</h2><h3 id="Single-line-comment"><a href="#Single-line-comment" class="headerlink" title="Single line comment"></a>Single line comment</h3><p>Single line comments start with // and can be found at any position in the line. The characters following //, till the end of the line, are considered part of the comment.</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// a standalone single line comment</span></span><br><span class="line">println <span class="string">"hello"</span> <span class="comment">// a comment till the end of the line</span></span><br></pre></td></tr></table></figure>
<h3 id="Multiline-comment"><a href="#Multiline-comment" class="headerlink" title="Multiline comment"></a>Multiline comment</h3><p>A multiline comment starts with /<em> and can be found at any position in the line. The characters following /</em> will be considered part of the comment, including new line characters, up to the first */ closing the comment. Multiline comments can thus be put at the end of a statement, or even inside a statement.</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* a standalone multiline comment</span></span><br><span class="line"><span class="comment">   spanning two lines */</span></span><br><span class="line">println <span class="string">"hello"</span> <span class="comment">/* a multiline comment starting</span></span><br><span class="line"><span class="comment">                   at the end of a statement */</span></span><br><span class="line">println <span class="number">1</span> <span class="comment">/* one */</span> + <span class="number">2</span> <span class="comment">/* two */</span></span><br></pre></td></tr></table></figure>
<h3 id="GroovyDoc-comment"><a href="#GroovyDoc-comment" class="headerlink" title="GroovyDoc comment"></a>GroovyDoc comment</h3><p>Similarly to multiline comments, GroovyDoc comments are multiline, but start with /*<em> and end with </em>/. Lines following the first GroovyDoc comment line can optionally start with a star *. Those comments are associated with:</p>
<ul>
<li>type definitions (classes, interfaces, enums, annotations),</li>
<li>fields and properties definitions</li>
<li>methods definitions</li>
</ul>
<p>Although the compiler will not complain about GroovyDoc comments not being associated with the above language elements, you should prepend those constructs with the comment right before it.</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * A Class description</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span> &#123;</span></span><br><span class="line">    <span class="comment">/** the name of the person */</span></span><br><span class="line">    String name</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Creates a greeting method for a certain person.</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> otherPerson the person to greet</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> a greeting message</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    String greet(String otherPerson) &#123;</span><br><span class="line">       <span class="string">"Hello $&#123;otherPerson&#125;"</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>GroovyDoc follows the same conventions as Java’s own JavaDoc. So you’ll be able to use the same tags as with JavaDoc.</p>
<h3 id="Shebang-line"><a href="#Shebang-line" class="headerlink" title="Shebang line"></a>Shebang line</h3><p>Beside the single line comment, there is a special line comment, often called the shebang line understood by UNIX systems which allows scripts to be run directly from the command-line, provided you have installed the Groovy distribution and the groovy command is available on the PATH.</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/usr/bin/env groovy</span></span><br><span class="line">println <span class="string">"Hello from the shebang line"</span></span><br></pre></td></tr></table></figure>
<p>The # character must be the first character of the file. Any indentation would yield a compilation error.</p>
<h2 id="Keywords"><a href="#Keywords" class="headerlink" title="Keywords"></a>Keywords</h2><p>The following list represents all the keywords of the Groovy language:</p>
<table>
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>as</td>
<td>assert</td>
<td>catch</td>
<td>class</td>
</tr>
<tr>
<td>break</td>
<td>case</td>
<td>const</td>
<td>continue</td>
</tr>
<tr>
<td>const</td>
<td>continue</td>
<td>def</td>
<td>default</td>
</tr>
<tr>
<td>do</td>
<td>else</td>
<td>enum</td>
<td>extends</td>
</tr>
<tr>
<td>false</td>
<td>finally</td>
<td>for</td>
<td>goto</td>
</tr>
<tr>
<td>if</td>
<td>implements</td>
<td>import</td>
<td>in</td>
</tr>
<tr>
<td>instanceof</td>
<td>interface</td>
<td>new</td>
<td>null</td>
</tr>
<tr>
<td>package</td>
<td>return</td>
<td>super</td>
<td>switch</td>
</tr>
<tr>
<td>this</td>
<td>throw</td>
<td>throws</td>
<td>trait</td>
</tr>
<tr>
<td>true</td>
<td>try</td>
<td>while</td>
</tr>
</tbody>
</table>
<h2 id="Identifiers"><a href="#Identifiers" class="headerlink" title="Identifiers"></a>Identifiers</h2><h3 id="Normal-identifiers"><a href="#Normal-identifiers" class="headerlink" title="Normal identifiers"></a>Normal identifiers</h3><p>Identifiers start with a letter, a dollar or an underscore. They cannot start with a number.</p>
<p>A letter can be in the following ranges:</p>
<ul>
<li>‘a’ to ‘z’ (lowercase ascii letter)</li>
<li>‘A’ to ‘Z’ (uppercase ascii letter)</li>
<li>‘\u00C0’ to ‘\u00D6’</li>
<li>‘\u00D8’ to ‘\u00F6’</li>
<li>‘\u00F8’ to ‘\u00FF’</li>
<li>‘\u0100’ to ‘\uFFFE’</li>
</ul>
<p>Then following characters can contain letters and numbers.</p>
<p>Here are a few examples of valid identifiers (here, variable names):</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> name</span><br><span class="line"><span class="keyword">def</span> item3</span><br><span class="line"><span class="keyword">def</span> with_underscore</span><br><span class="line"><span class="keyword">def</span> $dollarStart</span><br></pre></td></tr></table></figure>
<p>But the following ones are invalid identifiers:</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="number">3</span>tier</span><br><span class="line"><span class="keyword">def</span> a+b</span><br><span class="line">def a#b</span><br></pre></td></tr></table></figure>
<p>All keywords are also valid identifiers when following a dot:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">foo.<span class="keyword">as</span></span><br><span class="line">foo.<span class="keyword">assert</span></span><br><span class="line">foo.<span class="keyword">break</span></span><br><span class="line">foo.<span class="keyword">case</span></span><br><span class="line">foo.<span class="keyword">catch</span></span><br></pre></td></tr></table></figure>
<h3 id="Quoted-identifiers"><a href="#Quoted-identifiers" class="headerlink" title="Quoted identifiers"></a>Quoted identifiers</h3><p>Quoted identifiers appear after the dot of a dotted expression. For instance, the <code>name</code> part of the <code>person.name</code> expression can be quoted with <code>person.&quot;name&quot;</code> or <code>person.&#39;name&#39;</code>. This is particularly interesting when certain identifiers contain illegal characters that are forbidden by the Java Language Specification, but which are allowed by Groovy when quoted. For example, characters like a dash, a space, an exclamation mark, etc.</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> map = [:]</span><br><span class="line"></span><br><span class="line">map.<span class="string">"an identifier with a space and double quotes"</span> = <span class="string">"ALLOWED"</span></span><br><span class="line">map.<span class="string">'with-dash-signs-and-single-quotes'</span> = <span class="string">"ALLOWED"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> map.<span class="string">"an identifier with a space and double quotes"</span> == <span class="string">"ALLOWED"</span></span><br><span class="line"><span class="keyword">assert</span> map.<span class="string">'with-dash-signs-and-single-quotes'</span> == <span class="string">"ALLOWED"</span></span><br></pre></td></tr></table></figure>
<p>As we shall see in the following section on strings, Groovy provides different string literals. All kind of strings are actually allowed after the dot:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">map.<span class="string">'single quote'</span></span><br><span class="line">map.<span class="string">"double quote"</span></span><br><span class="line">map.<span class="string">'''triple single quote'''</span></span><br><span class="line">map.<span class="string">"""triple double quote"""</span></span><br><span class="line">map.<span class="regexp">/slashy string/</span></span><br><span class="line">map.<span class="string">$/dollar slashy string/$</span></span><br></pre></td></tr></table></figure>
<p>There’s a difference between plain character strings and Groovy’s GStrings (interpolated strings), as in that the latter case, the interpolated values are inserted in the final string for evaluating the whole identifier:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> firstname = <span class="string">"Homer"</span></span><br><span class="line">map.<span class="string">"Simpson-$&#123;firstname&#125;"</span> = <span class="string">"Homer Simpson"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> map.<span class="string">'Simpson-Homer'</span> == <span class="string">"Homer Simpson"</span></span><br></pre></td></tr></table></figure>
<h2 id="Strings"><a href="#Strings" class="headerlink" title="Strings"></a>Strings</h2><p>Text literals are represented in the form of chain of characters called strings. Groovy lets you instantiate java.lang.String objects, as well as GStrings (groovy.lang.GString) which are also called interpolated strings in other programming languages.</p>
<h3 id="Single-quoted-string"><a href="#Single-quoted-string" class="headerlink" title="Single quoted string"></a>Single quoted string</h3><p>Single quoted strings are a series of characters surrounded by single quotes:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">'a single quoted string'</span></span><br></pre></td></tr></table></figure>
<p>Single quoted strings are plain java.lang.String and don’t support interpolation.</p>
<h3 id="String-concatenation"><a href="#String-concatenation" class="headerlink" title="String concatenation"></a>String concatenation</h3><p>All the Groovy strings can be concatenated with the + operator:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">assert</span> <span class="string">'ab'</span> == <span class="string">'a'</span> + <span class="string">'b'</span></span><br></pre></td></tr></table></figure>
<h3 id="Triple-single-quoted-string"><a href="#Triple-single-quoted-string" class="headerlink" title="Triple single quoted string"></a>Triple single quoted string</h3><p>Triple single quoted strings are a series of characters surrounded by triplets of single quotes:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Triple single quoted strings are a series of characters surrounded by triplets of single <span class="string">quotes:</span></span><br></pre></td></tr></table></figure>
<p>Triple single quoted strings are plain java.lang.String and don’t support interpolation.</p>
<p>Triple single quoted strings are multiline. You can span the content of the string across line boundaries without the need to split the string in several pieces, without contatenation or newline escape characters:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> aMultilineString = <span class="string">'''line one</span></span><br><span class="line"><span class="string">line two</span></span><br><span class="line"><span class="string">line three'''</span></span><br></pre></td></tr></table></figure>
<p>If your code is indented, for example in the body of the method of a class, your string will contain the whitespace of the indentation. The Groovy Development Kit contains methods for stripping out the indentation with the String#stripIndent() method, and with the String#stripMargin() method that takes a delimiter character to identify the text to remove from the beginning of a string.</p>
<p>When creating a string as follows:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> startingAndEndingWithANewline = <span class="string">'''</span></span><br><span class="line"><span class="string">line one</span></span><br><span class="line"><span class="string">line two</span></span><br><span class="line"><span class="string">line three</span></span><br><span class="line"><span class="string">'''</span></span><br></pre></td></tr></table></figure>
<p>You will notice that the resulting string contains a newline character as first character. It is possible to strip that character by escaping the newline with a backslash:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> strippedFirstNewline = <span class="string">'''\</span></span><br><span class="line"><span class="string">line one</span></span><br><span class="line"><span class="string">line two</span></span><br><span class="line"><span class="string">line three</span></span><br><span class="line"><span class="string">'''</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> !strippedFirstNewline.startsWith(<span class="string">'\n'</span>)</span><br></pre></td></tr></table></figure>
<h3 id="Escaping-special-characters"><a href="#Escaping-special-characters" class="headerlink" title="Escaping special characters"></a>Escaping special characters</h3><p>You can escape single quotes with the the backslash character to avoid terminating the string literal:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">'an escaped single quote: \' needs a backslash'</span></span><br></pre></td></tr></table></figure>
<p>And you can escape the escape character itself with a double backslash:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">'an escaped escape character: \\ needs a double backslash'</span></span><br></pre></td></tr></table></figure>
<p>Some special characters also use the backslash as escape character:</p>
<table>
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>‘\t’</td>
<td>tabulation</td>
</tr>
<tr>
<td>‘\b’</td>
<td>backspace</td>
</tr>
<tr>
<td>‘\n’</td>
<td>newline</td>
</tr>
<tr>
<td>‘\r’</td>
<td>carriage return</td>
</tr>
<tr>
<td>‘\f’</td>
<td>formfeed</td>
</tr>
<tr>
<td>‘\‘</td>
<td>backslash</td>
</tr>
<tr>
<td>‘\’’</td>
<td>single quote (for single quoted and triple single quoted strings)</td>
</tr>
<tr>
<td>‘\”‘</td>
<td>double quote (for double quoted and triple double quoted strings)</td>
</tr>
</tbody>
</table>
<h3 id="Unicode-escape-sequence"><a href="#Unicode-escape-sequence" class="headerlink" title="Unicode escape sequence"></a>Unicode escape sequence</h3><p>For characters that are not present on your keyboard, you can use unicode escape sequences: a backslash, followed by ‘u’, then 4 hexadecimal digits.</p>
<p>For example, the Euro currency symbol can be represented with:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">'The Euro currency symbol: \u20AC'</span></span><br></pre></td></tr></table></figure>
<h3 id="Double-quoted-string"><a href="#Double-quoted-string" class="headerlink" title="Double quoted string"></a>Double quoted string</h3><p>Double quoted strings are a series of characters surrounded by double quotes:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">"a double quoted string"</span></span><br></pre></td></tr></table></figure>
<p>Double quoted strings are plain java.lang.String if there’s no interpolated expression, but are groovy.lang.GString instances if interpolation is present.</p>
<p>To escape a double quote, you can use the backslash character: “A double quote: \””.</p>
<h3 id="String-interpolation"><a href="#String-interpolation" class="headerlink" title="String interpolation"></a>String interpolation</h3><p>Any Groovy expression can be interpolated in all string literals, apart from single and triple single quoted strings. Interpolation is the act of replacing a placeholder in the string with its value upon evaluation of the string. The placeholder expressions are surrounded by ${} or prefixed with $ for dotted expressions. The expression value inside the placeholder is evaluated to its string representation when the GString is passed to a method taking a String as argument by calling toString() on that expression.</p>
<p>Here, we have a string with a placeholder referencing a local variable:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> name = <span class="string">'Guillaume'</span> <span class="comment">// a plain string</span></span><br><span class="line"><span class="keyword">def</span> greeting = <span class="string">"Hello $&#123;name&#125;"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> greeting.toString() == <span class="string">'Hello Guillaume'</span></span><br></pre></td></tr></table></figure>
<p>But any Groovy expression is valid, as we can see in this example with an arithmetic expression:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> sum = <span class="string">"The sum of 2 and 3 equals $&#123;2 + 3&#125;"</span></span><br><span class="line"><span class="keyword">assert</span> sum.toString() == <span class="string">'The sum of 2 and 3 equals 5'</span></span><br></pre></td></tr></table></figure>
<p>Not only are expressions allowed in between the ${} placeholder, but so are statements. However, a statement’s value is just null. So if several statements are inserted in that placeholder, the last one should somehow return a meaningful value to be inserted. For instance, “The sum of 1 and 2 is equal to ${def a = 1; def b = 2; a + b}” is supported and works as expected but a good practice is usually to stick to simple expressions inside GString placeholders.</p>
<p>In addition to ${} placeholders, we can also use a lone $ sign prefixing a dotted expression:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> person = [<span class="string">name:</span> <span class="string">'Guillaume'</span>, <span class="string">age:</span> <span class="number">36</span>]</span><br><span class="line"><span class="keyword">assert</span> <span class="string">"$person.name is $person.age years old"</span> == <span class="string">'Guillaume is 36 years old'</span></span><br></pre></td></tr></table></figure>
<p>But only dotted expressions of the form a.b, a.b.c, etc, are valid, but expressions that would contain parentheses like method calls, curly braces for closures, or arithmetic operators would be invalid. Given the following variable definition of a number:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> number = <span class="number">3.14</span></span><br></pre></td></tr></table></figure>
<p>The following statement will throw a groovy.lang.MissingPropertyException because Groovy believes you’re trying to access the toString property of that number, which doesn’t exist:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">shouldFail(MissingPropertyException) &#123;</span><br><span class="line">    println <span class="string">"$number.toString()"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>You can think of “$number.toString()” as being interpreted by the parser as “${number.toString()}”.</p>
<p>If you need to escape the $ or ${} placeholders in a GString so they appear as is without interpolation, you just need to use a \ backslash character to escape the dollar sign:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">assert</span> <span class="string">'$&#123;name&#125;'</span> == <span class="string">"\$&#123;name&#125;"</span></span><br></pre></td></tr></table></figure>
<h3 id="Special-case-of-interpolating-closure-expressions"><a href="#Special-case-of-interpolating-closure-expressions" class="headerlink" title="Special case of interpolating closure expressions"></a>Special case of interpolating closure expressions</h3><p>So far, we’ve seen we could interpolate arbitrary expressions inside the ${} placeholder, but there is a special case and notation for closure expressions. When the placeholder contains an arrow, ${→}, the expression is actually a closure expression — you can think of it as a closure with a dollar prepended in front of it:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> sParameterLessClosure = <span class="string">"1 + 2 == $&#123;-&gt; 3&#125;"</span> ①</span><br><span class="line"><span class="keyword">assert</span> sParameterLessClosure == <span class="string">'1 + 2 == 3'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> sOneParamClosure = <span class="string">"1 + 2 == $&#123; w -&gt; w &lt;&lt; 3&#125;"</span> ②</span><br><span class="line"><span class="keyword">assert</span> sOneParamClosure == <span class="string">'1 + 2 == 3'</span></span><br></pre></td></tr></table></figure>
<p>① The closure is a parameterless closure which doesn’t take arguments.</p>
<p>② Here, the closure takes a single java.io.StringWriter argument, to which you can append content with the &lt;&lt; leftShift operator. In either case, both placeholders are embedded closures.</p>
<p>In appearance, it looks like a more verbose way of defining expressions to be interpolated, but closures have an interesting advantage over mere expressions: lazy evaluation.</p>
<p>Let’s consider the following sample:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">def</span> number = <span class="number">1</span> ①</span><br><span class="line"><span class="keyword">def</span> eagerGString = <span class="string">"value == $&#123;number&#125;"</span></span><br><span class="line"><span class="keyword">def</span> lazyGString = <span class="string">"value == $&#123; -&gt; number &#125;"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> eagerGString == <span class="string">"value == 1"</span> ②</span><br><span class="line"><span class="keyword">assert</span> lazyGString ==  <span class="string">"value == 1"</span> ③</span><br><span class="line"></span><br><span class="line">number = <span class="number">2</span> ④</span><br><span class="line"><span class="keyword">assert</span> eagerGString == <span class="string">"value == 1"</span> ⑤</span><br><span class="line"><span class="keyword">assert</span> lazyGString ==  <span class="string">"value == 2"</span> ⑥</span><br></pre></td></tr></table></figure>
<p>① We define a number variable containing 1 that we then interpolate within two GStrings, as an expression in eagerGString and as a closure in lazyGString.</p>
<p>② We expect the resulting string to contain the same string value of 1 for eagerGString.</p>
<p>③ Similarly for lazyGString</p>
<p>④ Then we change the value of the variable to a new number</p>
<p>⑤ With a plain interpolated expression, the value was actually bound at the time of creation of the GString.</p>
<p>⑥ But with a closure expression, the closure is called upon each coercion of the GString into String, resulting in an updated string containing the new number value.</p>
<p>An embedded closure expression taking more than one parameter will generate an exception at runtime. Only closures with zero or one parameters are allowed.</p>
<h3 id="Interoperability-with-Java"><a href="#Interoperability-with-Java" class="headerlink" title="Interoperability with Java"></a>Interoperability with Java</h3><p>When a method (whether implemented in Java or Groovy) expects a java.lang.String, but we pass a groovy.lang.GString instance, the toString() method of the GString is automatically and transparently called.</p>
<p>String takeString(String message) { ④<br>    assert message instanceof String ⑤<br>    return message<br>}</p>
<p>def message = “The message is ${‘hello’}” ①<br>assert message instanceof GString ②</p>
<p>def result = takeString(message) ③<br>assert result instanceof String<br>assert result == ‘The message is hello’</p>
<p>① We create a GString variable</p>
<p>② We double check it’s an instance of the GString</p>
<p>③ We then pass that GString to a method taking a String as parameter</p>
<p>④ The signature of the takeString() method explicitly says its sole parameter is a String</p>
<p>⑤ We also verify that the parameter is indeed a String and not a GString.</p>
<h3 id="GString-and-String-hashCodes"><a href="#GString-and-String-hashCodes" class="headerlink" title="GString and String hashCodes"></a>GString and String hashCodes</h3><p>Although interpolated strings can be used in lieu of plain Java strings, they differ with strings in a particular way: their hashCodes are different. Plain Java strings are immutable, whereas the resulting String representation of a GString can vary, depending on its interpolated values. Even for the same resulting string, GStrings and Strings don’t have the same hashCode.</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">assert</span> <span class="string">"one: $&#123;1&#125;"</span>.hashCode() != <span class="string">"one: 1"</span>.hashCode()</span><br></pre></td></tr></table></figure>
<p>GString and Strings having different hashCode values, using GString as Map keys should be avoided, especially if we try to retrieve an associated value with a String instead of a GString.</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> key = <span class="string">"a"</span></span><br><span class="line"><span class="keyword">def</span> m = [<span class="string">"$&#123;key&#125;"</span>: <span class="string">"letter $&#123;key&#125;"</span>] ①</span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> m[<span class="string">"a"</span>] == <span class="literal">null</span> ②</span><br></pre></td></tr></table></figure>
<p>① The map is created with an initial pair whose key is a GString</p>
<p>② When we try to fetch the value with a String key, we will not find it, as Strings and GString have different hashCode values</p>
<h3 id="Triple-double-quoted-string"><a href="#Triple-double-quoted-string" class="headerlink" title="Triple double quoted string"></a>Triple double quoted string</h3><p>Triple double quoted strings behave like double quoted strings, with the addition that they are multiline, like the triple single quoted strings.</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> name = <span class="string">'Groovy'</span></span><br><span class="line"><span class="keyword">def</span> template = <span class="string">"""</span></span><br><span class="line"><span class="string">    Dear Mr $&#123;name&#125;,</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    You're the winner of the lottery!</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    Yours sincerly,</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    Dave</span></span><br><span class="line"><span class="string">"""</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> template.toString().contains(<span class="string">'Groovy'</span>)</span><br></pre></td></tr></table></figure>
<p>Neither double quotes nor single quotes need be escaped in triple double quoted strings.</p>
<h3 id="Slashy-string"><a href="#Slashy-string" class="headerlink" title="Slashy string"></a>Slashy string</h3><p>Beyond the usual quoted strings, Groovy offers slashy strings, which use / as delimiters. Slashy strings are particularly useful for defining regular expressions and patterns, as there is no need to escape backslashes.</p>
<p>Example of a slashy string:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> fooPattern = <span class="regexp">/.*foo.*/</span></span><br><span class="line"><span class="keyword">assert</span> fooPattern == <span class="string">'.*foo.*'</span></span><br></pre></td></tr></table></figure>
<p>Only forward slashes need to be escaped with a backslash:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> escapeSlash = <span class="regexp">/The character \/</span> is a forward slash/</span><br><span class="line"><span class="keyword">assert</span> escapeSlash == <span class="string">'The character / is a forward slash'</span></span><br></pre></td></tr></table></figure>
<p>Slashy strings are multiline:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> multilineSlashy = /one</span><br><span class="line">    two</span><br><span class="line">    three/</span><br><span class="line"><span class="keyword">assert</span> multilineSlashy.contains(<span class="string">'\n'</span>)</span><br></pre></td></tr></table></figure>
<p>Slashy strings can also be interpolated (ie. a GString):</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> color = <span class="string">'blue'</span></span><br><span class="line"><span class="keyword">def</span> interpolatedSlashy = <span class="regexp">/a $&#123;color&#125; car/</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> interpolatedSlashy == <span class="string">'a blue car'</span></span><br></pre></td></tr></table></figure>
<p>There are a few gotchas to be aware of.</p>
<p>An empty slashy string cannot be represented with a double forward slash, as it’s understood by the Groovy parser as a line comment. That’s why the following assert would actually not compile as it would look like a non-terminated statement:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">assert</span> <span class="string">''</span> == <span class="comment">//</span></span><br></pre></td></tr></table></figure>
<p>As slashy strings were mostly designed to make regexp easier so a few things that are errors in GStrings like $() will work with slashy strings.</p>
<h3 id="Dollar-slashy-string"><a href="#Dollar-slashy-string" class="headerlink" title="Dollar slashy string"></a>Dollar slashy string</h3><p>Dollar slashy strings are multiline GStrings delimited with an opening $/ and and a closing /$. The escaping character is the dollar sign, and it can escape another dollar, or a forward slash. But both dollar and forward slashes don’t need to be escaped, except to escape the dollar of a string subsequence that would start like a GString placeholder sequence, or if you need to escape a sequence that would start like a closing dollar slashy string delimiter.</p>
<p>Here’s an example:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> name = <span class="string">"Guillaume"</span></span><br><span class="line"><span class="keyword">def</span> date = <span class="string">"April, 1st"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> dollarSlashy = <span class="string">$/</span></span><br><span class="line"><span class="string">    Hello $name,</span></span><br><span class="line"><span class="string">    today we're $&#123;date&#125;.</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    $ dollar sign</span></span><br><span class="line"><span class="string">    $$ escaped dollar sign</span></span><br><span class="line"><span class="string">    \ backslash</span></span><br><span class="line"><span class="string">    / forward slash</span></span><br><span class="line"><span class="string">    $/ escaped forward slash</span></span><br><span class="line"><span class="string">    $$$/ escaped opening dollar slashy</span></span><br><span class="line"><span class="string">    $/$</span>$ escaped closing dollar slashy</span><br><span class="line">/$</span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> [</span><br><span class="line">    <span class="string">'Guillaume'</span>,</span><br><span class="line">    <span class="string">'April, 1st'</span>,</span><br><span class="line">    <span class="string">'$ dollar sign'</span>,</span><br><span class="line">    <span class="string">'$ escaped dollar sign'</span>,</span><br><span class="line">    <span class="string">'\\ backslash'</span>,</span><br><span class="line">    <span class="string">'/ forward slash'</span>,</span><br><span class="line">    <span class="string">'/ escaped forward slash'</span>,</span><br><span class="line">    <span class="string">'$/ escaped opening dollar slashy'</span>,</span><br><span class="line">    <span class="string">'/$ escaped closing dollar slashy'</span></span><br><span class="line">].every &#123; dollarSlashy.contains(it) &#125;</span><br></pre></td></tr></table></figure>
<h3 id="String-summary-table"><a href="#String-summary-table" class="headerlink" title="String summary table"></a>String summary table</h3><table>
<thead>
<tr>
<th>String name</th>
<th>String syntax</th>
<th>Interpolated</th>
<th>Multiline</th>
<th>Escape character</th>
</tr>
</thead>
<tbody>
<tr>
<td>Single quoted</td>
<td>‘…​’</td>
<td></td>
<td></td>
<td>\</td>
</tr>
<tr>
<td>Triple single quoted</td>
<td>‘’’…​’’’</td>
<td></td>
<td>√</td>
<td>\</td>
</tr>
<tr>
<td>Double quoted</td>
<td>‘’…​’’</td>
<td>√</td>
<td></td>
<td>\</td>
</tr>
<tr>
<td>Triple double quoted</td>
<td>“””…”””</td>
<td>√</td>
<td>√</td>
<td>\</td>
</tr>
<tr>
<td>Slashy</td>
<td>/…​/</td>
<td>√</td>
<td>√</td>
<td>\</td>
</tr>
<tr>
<td>Dollar slashy</td>
<td>\$/…​/\$</td>
<td>√</td>
<td>√</td>
<td>$</td>
</tr>
</tbody>
</table>
<h3 id="Characters"><a href="#Characters" class="headerlink" title="Characters"></a>Characters</h3><p>Unlike Java, Groovy doesn’t have an explicit character literal. However, you can be explicit about making a Groovy string an actual character, by three different means:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">char</span> c1 = <span class="string">'A'</span> ①</span><br><span class="line"><span class="keyword">assert</span> c1 <span class="keyword">instanceof</span> Character</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> c2 = <span class="string">'B'</span> <span class="keyword">as</span> <span class="keyword">char</span> ②</span><br><span class="line"><span class="keyword">assert</span> c2 <span class="keyword">instanceof</span> Character</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> c3 = (<span class="keyword">char</span>)<span class="string">'C'</span> ③</span><br><span class="line"><span class="keyword">assert</span> c3 <span class="keyword">instanceof</span> Character</span><br></pre></td></tr></table></figure>
<p>① by being explicit when declaring a variable holding the character by specifying the char type</p>
<p>② by using type coercion with the as operator</p>
<p>③ by using a cast to char operation</p>
<p>The first option ① is interesting when the character is held in a variable, while the other two (② and ③) are more interesting when a char value must be passed as argument of a method call.</p>
<h2 id="Numbers"><a href="#Numbers" class="headerlink" title="Numbers"></a>Numbers</h2><h3 id="Integral-literals"><a href="#Integral-literals" class="headerlink" title="Integral literals"></a>Integral literals</h3><p>The integral literal types are the same as in Java:</p>
<ul>
<li><p>byte</p>
</li>
<li><p>char</p>
</li>
<li><p>short</p>
</li>
<li><p>int</p>
</li>
<li><p>long</p>
</li>
<li><p>java.lang.BigInteger</p>
</li>
</ul>
<p>You can create integral numbers of those types with the following declarations:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// primitive types</span></span><br><span class="line"><span class="keyword">byte</span>  b = <span class="number">1</span></span><br><span class="line"><span class="keyword">char</span>  c = <span class="number">2</span></span><br><span class="line"><span class="keyword">short</span> s = <span class="number">3</span></span><br><span class="line"><span class="keyword">int</span>   i = <span class="number">4</span></span><br><span class="line"><span class="keyword">long</span>  l = <span class="number">5</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// infinite precision</span></span><br><span class="line">BigInteger bi =  <span class="number">6</span></span><br></pre></td></tr></table></figure>
<p>If you use optional typing by using the def keyword, the type of the integral number will vary: it’ll adapt to the capacity of the type that can hold that number.</p>
<p>For positive numbers:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> a = <span class="number">1</span></span><br><span class="line"><span class="keyword">assert</span> a <span class="keyword">instanceof</span> Integer</span><br><span class="line"></span><br><span class="line"><span class="comment">// Integer.MAX_VALUE</span></span><br><span class="line"><span class="keyword">def</span> b = <span class="number">2147483647</span></span><br><span class="line"><span class="keyword">assert</span> b <span class="keyword">instanceof</span> Integer</span><br><span class="line"></span><br><span class="line"><span class="comment">// Integer.MAX_VALUE + 1</span></span><br><span class="line"><span class="keyword">def</span> c = <span class="number">2147483648</span></span><br><span class="line"><span class="keyword">assert</span> c <span class="keyword">instanceof</span> Long</span><br><span class="line"></span><br><span class="line"><span class="comment">// Long.MAX_VALUE</span></span><br><span class="line"><span class="keyword">def</span> d = <span class="number">9223372036854775807</span></span><br><span class="line"><span class="keyword">assert</span> d <span class="keyword">instanceof</span> Long</span><br><span class="line"></span><br><span class="line"><span class="comment">// Long.MAX_VALUE + 1</span></span><br><span class="line"><span class="keyword">def</span> e = <span class="number">9223372036854775808</span></span><br><span class="line"><span class="keyword">assert</span> e <span class="keyword">instanceof</span> BigInteger</span><br></pre></td></tr></table></figure>
<p>As well as for negative numbers:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> na = <span class="number">-1</span></span><br><span class="line"><span class="keyword">assert</span> na <span class="keyword">instanceof</span> Integer</span><br><span class="line"></span><br><span class="line"><span class="comment">// Integer.MIN_VALUE</span></span><br><span class="line"><span class="keyword">def</span> nb = <span class="number">-2147483648</span></span><br><span class="line"><span class="keyword">assert</span> nb <span class="keyword">instanceof</span> Integer</span><br><span class="line"></span><br><span class="line"><span class="comment">// Integer.MIN_VALUE - 1</span></span><br><span class="line"><span class="keyword">def</span> nc = <span class="number">-2147483649</span></span><br><span class="line"><span class="keyword">assert</span> nc <span class="keyword">instanceof</span> Long</span><br><span class="line"></span><br><span class="line"><span class="comment">// Long.MIN_VALUE</span></span><br><span class="line"><span class="keyword">def</span> nd = <span class="number">-9223372036854775808</span></span><br><span class="line"><span class="keyword">assert</span> nd <span class="keyword">instanceof</span> Long</span><br><span class="line"></span><br><span class="line"><span class="comment">// Long.MIN_VALUE - 1</span></span><br><span class="line"><span class="keyword">def</span> ne = <span class="number">-9223372036854775809</span></span><br><span class="line"><span class="keyword">assert</span> ne <span class="keyword">instanceof</span> BigInteger</span><br></pre></td></tr></table></figure>
<h4 id="Alternative-non-base-10-representations"><a href="#Alternative-non-base-10-representations" class="headerlink" title="Alternative non-base 10 representations"></a>Alternative non-base 10 representations</h4><p>Numbers can also be represented in binary, octal, hexadecimal and decimal bases.</p>
<h5 id="Binary-literal"><a href="#Binary-literal" class="headerlink" title="Binary literal"></a>Binary literal</h5><p>Binary numbers start with a 0b prefix:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> xInt = <span class="number">0b10101111</span></span><br><span class="line"><span class="keyword">assert</span> xInt == <span class="number">175</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">short</span> xShort = <span class="number">0b11001001</span></span><br><span class="line"><span class="keyword">assert</span> xShort == <span class="number">201</span> <span class="keyword">as</span> <span class="keyword">short</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">byte</span> xByte = <span class="number">0b11</span></span><br><span class="line"><span class="keyword">assert</span> xByte == <span class="number">3</span> <span class="keyword">as</span> <span class="keyword">byte</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">long</span> xLong = <span class="number">0b101101101101</span></span><br><span class="line"><span class="keyword">assert</span> xLong == <span class="number">2925</span>l</span><br><span class="line"></span><br><span class="line">BigInteger xBigInteger = <span class="number">0b111100100001</span></span><br><span class="line"><span class="keyword">assert</span> xBigInteger == <span class="number">3873</span>g</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> xNegativeInt = <span class="number">-0</span>b10101111</span><br><span class="line"><span class="keyword">assert</span> xNegativeInt == <span class="number">-175</span></span><br></pre></td></tr></table></figure>
<h5 id="Octal-literal"><a href="#Octal-literal" class="headerlink" title="Octal literal"></a>Octal literal</h5><p>Octal numbers are specified in the typical format of 0 followed by octal digits.</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> xInt = <span class="number">077</span></span><br><span class="line"><span class="keyword">assert</span> xInt == <span class="number">63</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">short</span> xShort = <span class="number">011</span></span><br><span class="line"><span class="keyword">assert</span> xShort == <span class="number">9</span> <span class="keyword">as</span> <span class="keyword">short</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">byte</span> xByte = <span class="number">032</span></span><br><span class="line"><span class="keyword">assert</span> xByte == <span class="number">26</span> <span class="keyword">as</span> <span class="keyword">byte</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">long</span> xLong = <span class="number">0246</span></span><br><span class="line"><span class="keyword">assert</span> xLong == <span class="number">166</span>l</span><br><span class="line"></span><br><span class="line">BigInteger xBigInteger = <span class="number">01111</span></span><br><span class="line"><span class="keyword">assert</span> xBigInteger == <span class="number">585</span>g</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> xNegativeInt = <span class="number">-077</span></span><br><span class="line"><span class="keyword">assert</span> xNegativeInt == <span class="number">-63</span></span><br></pre></td></tr></table></figure>
<h5 id="Hexadecimal-literal"><a href="#Hexadecimal-literal" class="headerlink" title="Hexadecimal literal"></a>Hexadecimal literal</h5><p>Hexadecimal numbers are specified in the typical format of 0x followed by hex digits.</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> xInt = <span class="number">0x77</span></span><br><span class="line"><span class="keyword">assert</span> xInt == <span class="number">119</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">short</span> xShort = <span class="number">0xaa</span></span><br><span class="line"><span class="keyword">assert</span> xShort == <span class="number">170</span> <span class="keyword">as</span> <span class="keyword">short</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">byte</span> xByte = <span class="number">0x3a</span></span><br><span class="line"><span class="keyword">assert</span> xByte == <span class="number">58</span> <span class="keyword">as</span> <span class="keyword">byte</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">long</span> xLong = <span class="number">0xffff</span></span><br><span class="line"><span class="keyword">assert</span> xLong == <span class="number">65535</span>l</span><br><span class="line"></span><br><span class="line">BigInteger xBigInteger = <span class="number">0xaaaa</span></span><br><span class="line"><span class="keyword">assert</span> xBigInteger == <span class="number">43690</span>g</span><br><span class="line"></span><br><span class="line">Double xDouble = <span class="keyword">new</span> Double(<span class="string">'0x1.0p0'</span>)</span><br><span class="line"><span class="keyword">assert</span> xDouble == <span class="number">1.0</span>d</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> xNegativeInt = <span class="number">-0x77</span></span><br><span class="line"><span class="keyword">assert</span> xNegativeInt == <span class="number">-119</span></span><br></pre></td></tr></table></figure>
<h3 id="Decimal-literals"><a href="#Decimal-literals" class="headerlink" title="Decimal literals"></a>Decimal literals</h3><p>The decimal literal types are the same as in Java:</p>
<ul>
<li>float</li>
<li>double</li>
<li>java.lang.BigDecimal</li>
</ul>
<p>You can create decimal numbers of those types with the following declarations:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// primitive types</span></span><br><span class="line"><span class="keyword">float</span>  f = <span class="number">1.234</span></span><br><span class="line"><span class="keyword">double</span> d = <span class="number">2.345</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// infinite precision</span></span><br><span class="line">BigDecimal bd =  <span class="number">3.456</span></span><br></pre></td></tr></table></figure>
<p>Decimals can use exponents, with the e or E exponent letter, followed by an optional sign, and a integral number representing the exponent:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">assert</span> <span class="number">1e3</span>  ==  <span class="number">1</span>_000<span class="number">.0</span></span><br><span class="line"><span class="keyword">assert</span> <span class="number">2E4</span>  == <span class="number">20</span>_000<span class="number">.0</span></span><br><span class="line"><span class="keyword">assert</span> <span class="number">3e+1</span> ==     <span class="number">30.0</span></span><br><span class="line"><span class="keyword">assert</span> <span class="number">4E-2</span> ==      <span class="number">0.04</span></span><br><span class="line"><span class="keyword">assert</span> <span class="number">5e-1</span> ==      <span class="number">0.5</span></span><br></pre></td></tr></table></figure>
<p>Conveniently for exact decimal number calculations, Groovy choses java.lang.BigDecimal as its decimal number type. In addition, both float and double are supported, but require an explicit type declaration, type coercion or suffix. Even if BigDecimal is the default for decimal numbers, such literals are accepted in methods or closures taking float or double as parameter types.</p>
<p>Decimal numbers can’t be represented using a binary, octal or hexadecimal representation.</p>
<h3 id="Underscore-in-literals"><a href="#Underscore-in-literals" class="headerlink" title="Underscore in literals"></a>Underscore in literals</h3><p>When writing long literal numbers, it’s harder on the eye to figure out how some numbers are grouped together, for example with groups of thousands, of words, etc. By allowing you to place underscore in number literals, it’s easier to spot those groups:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">long</span> creditCardNumber = <span class="number">1234</span>_5678_9012_3456L</span><br><span class="line"><span class="keyword">long</span> socialSecurityNumbers = <span class="number">999</span>_99_9999L</span><br><span class="line"><span class="keyword">double</span> monetaryAmount = <span class="number">12</span>_345_132<span class="number">.12</span></span><br><span class="line"><span class="keyword">long</span> hexBytes = <span class="number">0xFF</span>_EC_DE_5E</span><br><span class="line"><span class="keyword">long</span> hexWords = <span class="number">0xFFEC</span>_DE5E</span><br><span class="line"><span class="keyword">long</span> maxLong = <span class="number">0x7fff</span>_ffff_ffff_ffffL</span><br><span class="line"><span class="keyword">long</span> alsoMaxLong = <span class="number">9</span>_223_372_036_854_775_807L</span><br><span class="line"><span class="keyword">long</span> bytes = <span class="number">0b11010010</span>_01101001_10010100_10010010</span><br></pre></td></tr></table></figure>
<h3 id="Number-type-suffixes"><a href="#Number-type-suffixes" class="headerlink" title="Number type suffixes"></a>Number type suffixes</h3><p>We can force a number (including binary, octals and hexadecimals) to have a specific type by giving a suffix (see table below), either uppercase or lowercase.</p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Suffix</th>
</tr>
</thead>
<tbody>
<tr>
<td>BigInteger</td>
<td>G or g</td>
</tr>
<tr>
<td>Long</td>
<td>L or l</td>
</tr>
<tr>
<td>Integer</td>
<td>I or i</td>
</tr>
<tr>
<td>BigDecimal</td>
<td>G or g</td>
</tr>
<tr>
<td>Double</td>
<td>D or d</td>
</tr>
<tr>
<td>Float</td>
<td>F or f</td>
</tr>
</tbody>
</table>
<p>Examples:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">assert</span> <span class="number">42</span>I == <span class="keyword">new</span> Integer(<span class="string">'42'</span>)</span><br><span class="line"><span class="keyword">assert</span> <span class="number">42</span>i == <span class="keyword">new</span> Integer(<span class="string">'42'</span>) <span class="comment">// lowercase i more readable</span></span><br><span class="line"><span class="keyword">assert</span> <span class="number">123</span>L == <span class="keyword">new</span> Long(<span class="string">"123"</span>) <span class="comment">// uppercase L more readable</span></span><br><span class="line"><span class="keyword">assert</span> <span class="number">2147483648</span> == <span class="keyword">new</span> Long(<span class="string">'2147483648'</span>) <span class="comment">// Long type used, value too large for an Integer</span></span><br><span class="line"><span class="keyword">assert</span> <span class="number">456</span>G == <span class="keyword">new</span> BigInteger(<span class="string">'456'</span>)</span><br><span class="line"><span class="keyword">assert</span> <span class="number">456</span>g == <span class="keyword">new</span> BigInteger(<span class="string">'456'</span>)</span><br><span class="line"><span class="keyword">assert</span> <span class="number">123.45</span> == <span class="keyword">new</span> BigDecimal(<span class="string">'123.45'</span>) <span class="comment">// default BigDecimal type used</span></span><br><span class="line"><span class="keyword">assert</span> <span class="number">1.200065</span>D == <span class="keyword">new</span> Double(<span class="string">'1.200065'</span>)</span><br><span class="line"><span class="keyword">assert</span> <span class="number">1.234</span>F == <span class="keyword">new</span> Float(<span class="string">'1.234'</span>)</span><br><span class="line"><span class="keyword">assert</span> <span class="number">1.23E23</span>D == <span class="keyword">new</span> Double(<span class="string">'1.23E23'</span>)</span><br><span class="line"><span class="keyword">assert</span> <span class="number">0b1111</span>L.<span class="keyword">class</span> == Long <span class="comment">// binary</span></span><br><span class="line"><span class="keyword">assert</span> <span class="number">0xFF</span>i.<span class="keyword">class</span> == Integer <span class="comment">// hexadecimal</span></span><br><span class="line"><span class="keyword">assert</span> <span class="number">034</span>G.<span class="keyword">class</span> == BigInteger <span class="comment">// octal</span></span><br></pre></td></tr></table></figure>
<h3 id="Math-operations"><a href="#Math-operations" class="headerlink" title="Math operations"></a>Math operations</h3><p>Although operators are covered later on, it’s important to discuss the behavior of math operations and what their resulting types are.</p>
<p>Division and power binary operations aside (covered below),</p>
<ul>
<li><p>binary operations between byte, char, short and int result in int</p>
</li>
<li><p>binary operations involving long with byte, char, short and int result in long</p>
</li>
<li><p>binary operations involving BigInteger and any other integral type result in BigInteger</p>
</li>
<li><p>binary operations involving BigDecimal with byte, char, short, int and BigInteger result in BigDecimal</p>
</li>
<li><p>binary operations between float, double and BigDecimal result in double</p>
</li>
<li><p>binary operations between two BigDecimal result in BigDecimal</p>
</li>
</ul>
<p>The following table summarizes those rules:</p>
<table>
<thead>
<tr>
<th></th>
<th>byte</th>
<th>char</th>
<th>short</th>
<th>int</th>
<th>long</th>
<th>BigInteger</th>
<th>float</th>
<th>double</th>
<th>BigDecimal</th>
</tr>
</thead>
<tbody>
<tr>
<td>byte</td>
<td>byte</td>
<td>char</td>
<td>short</td>
<td>int</td>
<td>long</td>
<td>BigInteger</td>
<td>float</td>
<td>double</td>
<td>BigDecimal</td>
</tr>
<tr>
<td>char</td>
<td></td>
<td>char</td>
<td>short</td>
<td>int</td>
<td>long</td>
<td>BigInteger</td>
<td>float</td>
<td>double</td>
<td>BigDecimal</td>
</tr>
<tr>
<td>short</td>
<td></td>
<td></td>
<td>short</td>
<td>int</td>
<td>long</td>
<td>BigInteger</td>
<td>float</td>
<td>double</td>
<td>BigDecimal</td>
</tr>
<tr>
<td>int</td>
<td></td>
<td></td>
<td></td>
<td>int</td>
<td>long</td>
<td>BigInteger</td>
<td>float</td>
<td>double</td>
<td>BigDecimal</td>
</tr>
<tr>
<td>long</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>long</td>
<td>BigInteger</td>
<td>float</td>
<td>double</td>
<td>BigDecimal</td>
</tr>
<tr>
<td>BigInteger</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>BigInteger</td>
<td>float</td>
<td>double</td>
<td>BigDecimal</td>
</tr>
<tr>
<td>float</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>float</td>
<td>double</td>
<td>BigDecimal</td>
</tr>
<tr>
<td>double</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>double</td>
<td>BigDecimal</td>
</tr>
<tr>
<td>BigDecimal</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>BigDecimal</td>
</tr>
</tbody>
</table>
<p>Thanks to Groovy’s operator overloading, the usual arithmetic operators work as well with BigInteger and BigDecimal, unlike in Java where you have to use explicit methods for operating on those numbers.</p>
<h4 id="The-case-of-the-division-operator"><a href="#The-case-of-the-division-operator" class="headerlink" title="The case of the division operator"></a>The case of the division operator</h4><p>The division operators / (and /= for division and assignment) produce a double result if either operand is a float or double, and a BigDecimal result otherwise (when both operands are any combination of an integral type short, char, byte, int, long, BigInteger or BigDecimal).</p>
<p>BigDecimal division is performed with the divide() method if the division is exact (i.e. yielding a result that can be represented within the bounds of the same precision and scale), or using a MathContext with a precision of the maximum of the two operands’ precision plus an extra precision of 10, and a scale of the maximum of 10 and the maximum of the operands’ scale.</p>
<p>For integer division like in Java, you should use the intdiv() method, as Groovy doesn’t provide a dedicated integer division operator symbol.</p>
<h4 id="The-case-of-the-power-operator"><a href="#The-case-of-the-power-operator" class="headerlink" title="The case of the power operator"></a>The case of the power operator</h4><p>The power operation is represented by the ** operator, with two parameters: the base and the exponent. The result of the power operation depends on its operands, and the result of the operation (in particular if the result can be represented as an integral value).</p>
<p>The following rules are used by Groovy’s power operation to determine the resulting type:</p>
<ul>
<li>If the exponent is a decimal value<ul>
<li>if the result can be represented as an Integer, then return an Integer</li>
<li>else if the result can be represented as a Long, then return a Long</li>
<li>otherwise return a Double</li>
</ul>
</li>
<li>If the exponent is an integral value<ul>
<li>if the exponent is strictly negative, then return an Integer, Long or Double if the result value fits in that type</li>
<li>if the exponent is positive or zero<ul>
<li>if the base is a BigDecimal, then return a BigDecimal result value</li>
<li>if the base is a BigInteger, then return a BigInteger result value</li>
<li>if the base is an Integer, then return an Integer if the result value fits in it, otherwise a BigInteger</li>
<li>if the base is a Long, then return a Long if the result value fits in it, otherwise a BigInteger</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>We can illustrate those rules with a few examples:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// base and exponent are ints and the result can be represented by an Integer</span></span><br><span class="line"><span class="keyword">assert</span>    <span class="number">2</span>    **   <span class="number">3</span>    <span class="keyword">instanceof</span> Integer    <span class="comment">//  8</span></span><br><span class="line"><span class="keyword">assert</span>   <span class="number">10</span>    **   <span class="number">9</span>    <span class="keyword">instanceof</span> Integer    <span class="comment">//  1_000_000_000</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// the base is a long, so fit the result in a Long</span></span><br><span class="line"><span class="comment">// (although it could have fit in an Integer)</span></span><br><span class="line"><span class="keyword">assert</span>    <span class="number">5</span>L   **   <span class="number">2</span>    <span class="keyword">instanceof</span> Long       <span class="comment">//  25</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// the result can't be represented as an Integer or Long, so return a BigInteger</span></span><br><span class="line"><span class="keyword">assert</span>  <span class="number">100</span>    **  <span class="number">10</span>    <span class="keyword">instanceof</span> BigInteger <span class="comment">//  10e20</span></span><br><span class="line"><span class="keyword">assert</span> <span class="number">1234</span>    ** <span class="number">123</span>    <span class="keyword">instanceof</span> BigInteger <span class="comment">//  170515806212727042875...</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// the base is a BigDecimal and the exponent a negative int</span></span><br><span class="line"><span class="comment">// but the result can be represented as an Integer</span></span><br><span class="line"><span class="keyword">assert</span>    <span class="number">0.5</span>  **  <span class="number">-2</span>    <span class="keyword">instanceof</span> Integer    <span class="comment">//  4</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// the base is an int, and the exponent a negative float</span></span><br><span class="line"><span class="comment">// but again, the result can be represented as an Integer</span></span><br><span class="line"><span class="keyword">assert</span>    <span class="number">1</span>    **  <span class="number">-0.3</span>f <span class="keyword">instanceof</span> Integer    <span class="comment">//  1</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// the base is an int, and the exponent a negative int</span></span><br><span class="line"><span class="comment">// but the result will be calculated as a Double</span></span><br><span class="line"><span class="comment">// (both base and exponent are actually converted to doubles)</span></span><br><span class="line"><span class="keyword">assert</span>   <span class="number">10</span>    **  <span class="number">-1</span>    <span class="keyword">instanceof</span> Double     <span class="comment">//  0.1</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// the base is a BigDecimal, and the exponent is an int, so return a BigDecimal</span></span><br><span class="line"><span class="keyword">assert</span>    <span class="number">1.2</span>  **  <span class="number">10</span>    <span class="keyword">instanceof</span> BigDecimal <span class="comment">//  6.1917364224</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// the base is a float or double, and the exponent is an int</span></span><br><span class="line"><span class="comment">// but the result can only be represented as a Double value</span></span><br><span class="line"><span class="keyword">assert</span>    <span class="number">3.4</span>f **   <span class="number">5</span>    <span class="keyword">instanceof</span> Double     <span class="comment">//  454.35430372146965</span></span><br><span class="line"><span class="keyword">assert</span>    <span class="number">5.6</span>d **   <span class="number">2</span>    <span class="keyword">instanceof</span> Double     <span class="comment">//  31.359999999999996</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// the exponent is a decimal value</span></span><br><span class="line"><span class="comment">// and the result can only be represented as a Double value</span></span><br><span class="line"><span class="keyword">assert</span>    <span class="number">7.8</span>  **   <span class="number">1.9</span>  <span class="keyword">instanceof</span> Double     <span class="comment">//  49.542708423868476</span></span><br><span class="line"><span class="keyword">assert</span>    <span class="number">2</span>    **   <span class="number">0.1</span>f <span class="keyword">instanceof</span> Double     <span class="comment">//  1.0717734636432956</span></span><br></pre></td></tr></table></figure>
<h2 id="Booleans"><a href="#Booleans" class="headerlink" title="Booleans"></a>Booleans</h2><p>Boolean is a special data type that is used to represent truth values: true and false. Use this data type for simple flags that track true/false conditions.</p>
<p>Boolean values can be stored in variables, assigned into fields, just like any other data type:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> myBooleanVariable = <span class="literal">true</span></span><br><span class="line"><span class="keyword">boolean</span> untypedBooleanVar = <span class="literal">false</span></span><br><span class="line">booleanField = <span class="literal">true</span></span><br></pre></td></tr></table></figure>
<p>true and false are the only two primitive boolean values. But more complex boolean expressions can be represented using logical operators.</p>
<p>In addition, Groovy has special rules (often referred to as Groovy Truth) for coercing non-boolean objects to a boolean value.</p>
<h2 id="Lists"><a href="#Lists" class="headerlink" title="Lists"></a>Lists</h2><p>Groovy uses a comma-separated list of values, surrounded by square brackets, to denote lists. Groovy lists are plain JDK java.util.List, as Groovy doesn’t define its own collection classes. The concrete list implementation used when defining list literals are java.util.ArrayList by default, unless you decide to specify otherwise, as we shall see later on.</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> numbers = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>] ①</span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> numbers <span class="keyword">instanceof</span> List  </span><br><span class="line"><span class="keyword">assert</span> numbers.size() == <span class="number">3</span> ②</span><br></pre></td></tr></table></figure>
<p>① We define a list numbers delimited by commas and surrounded by square brackets, and we assign that list into a variable</p>
<p>② The list is an instance of Java’s java.util.List interface</p>
<p>③ The size of the list can be queried with the size() method, and shows our list contains 3 elements</p>
<p>In the above example, we used a homogeneous list, but you can also create lists containing values of heterogeneous types:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> heterogeneous = [<span class="number">1</span>, <span class="string">"a"</span>, <span class="literal">true</span>]  ①</span><br></pre></td></tr></table></figure>
<p>① Our list here contains a number, a string and a boolean value</p>
<p>We mentioned that by default, list literals are actually instances of java.util.ArrayList, but it is possible to use a different backing type for our lists, thanks to using type coercion with the as operator, or with explicit type declaration for your variables:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> arrayList = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line"><span class="keyword">assert</span> arrayList <span class="keyword">instanceof</span> java.util.ArrayList</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> linkedList = [<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>] <span class="keyword">as</span> LinkedList ①</span><br><span class="line"><span class="keyword">assert</span> linkedList <span class="keyword">instanceof</span> java.util.LinkedList</span><br><span class="line"></span><br><span class="line">LinkedList otherLinked = [<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>] ②</span><br><span class="line"><span class="keyword">assert</span> otherLinked <span class="keyword">instanceof</span> java.util.LinkedList</span><br></pre></td></tr></table></figure>
<p>① We use coercion with the as operator to explicitly request a java.util.LinkedList implementation</p>
<p>② We can say that the variable holding the list literal is of type java.util.LinkedList</p>
<p>You can access elements of the list with the [] subscript operator (both for reading and setting values) with positive indices or negative indices to access elements from the end of the list, as well as with ranges, and use the &lt;&lt; leftShift operator to append elements to a list:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> letters = [<span class="string">'a'</span>, <span class="string">'b'</span>, <span class="string">'c'</span>, <span class="string">'d'</span>]</span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> letters[<span class="number">0</span>] == <span class="string">'a'</span> ①</span><br><span class="line"><span class="keyword">assert</span> letters[<span class="number">1</span>] == <span class="string">'b'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> letters[<span class="number">-1</span>] == <span class="string">'d'</span> ②</span><br><span class="line"><span class="keyword">assert</span> letters[<span class="number">-2</span>] == <span class="string">'c'</span></span><br><span class="line"></span><br><span class="line">letters[<span class="number">2</span>] = <span class="string">'C'</span> ③</span><br><span class="line"><span class="keyword">assert</span> letters[<span class="number">2</span>] == <span class="string">'C'</span></span><br><span class="line"></span><br><span class="line">letters &lt;&lt; <span class="string">'e'</span> ④</span><br><span class="line"><span class="keyword">assert</span> letters[ <span class="number">4</span>] == <span class="string">'e'</span></span><br><span class="line"><span class="keyword">assert</span> letters[<span class="number">-1</span>] == <span class="string">'e'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> letters[<span class="number">1</span>, <span class="number">3</span>] == [<span class="string">'b'</span>, <span class="string">'d'</span>] ⑤</span><br><span class="line"><span class="keyword">assert</span> letters[<span class="number">2.</span><span class="number">.4</span>] == [<span class="string">'C'</span>, <span class="string">'d'</span>, <span class="string">'e'</span>] ⑥</span><br></pre></td></tr></table></figure>
<p>① Access the first element of the list (zero-based counting)</p>
<p>② Access the last element of the list with a negative index: -1 is the first element from the end of the list</p>
<p>③ Use an assignment to set a new value for the third element of the list</p>
<p>④ Use the &lt;&lt; leftShift operator to append an element at the end of the list</p>
<p>⑤ Access two elements at once, returning a new list containing those two elements</p>
<p>⑥ Use a range to access a range of values from the list, from a start to an end element position</p>
<p>As lists can be heterogeneous in nature, lists can also contain other lists to create multi-dimensional lists:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> multi = [[<span class="number">0</span>, <span class="number">1</span>], [<span class="number">2</span>, <span class="number">3</span>]] ①</span><br><span class="line"><span class="keyword">assert</span> multi[<span class="number">1</span>][<span class="number">0</span>] == <span class="number">2</span> ②</span><br></pre></td></tr></table></figure>
<p>① Define a list of list of numbers</p>
<p>② Access the second element of the top-most list, and the first element of the inner list</p>
<h2 id="Arrays"><a href="#Arrays" class="headerlink" title="Arrays"></a>Arrays</h2><p>Groovy reuses the list notation for arrays, but to make such literals arrays, you need to explicitely define the type of the array through coercion or type declaration.</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">String[] arrStr = [<span class="string">'Ananas'</span>, <span class="string">'Banana'</span>, <span class="string">'Kiwi'</span>]  ①</span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> arrStr <span class="keyword">instanceof</span> String[] ②</span><br><span class="line"><span class="keyword">assert</span> !(arrStr <span class="keyword">instanceof</span> List)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> numArr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>] <span class="keyword">as</span> <span class="keyword">int</span>[] ③</span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> numArr <span class="keyword">instanceof</span> <span class="keyword">int</span>[] ④</span><br><span class="line"><span class="keyword">assert</span> numArr.size() == <span class="number">3</span></span><br></pre></td></tr></table></figure>
<p>① Define an array of strings using explicit variable type declaration</p>
<p>② Assert that we created an array of strings</p>
<p>③ Create an array of ints with the as operator</p>
<p>④ Assert that we created an array of primitive ints</p>
<p>You can also create multi-dimensional arrays:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> matrix3 = <span class="keyword">new</span> Integer[<span class="number">3</span>][<span class="number">3</span>] ①</span><br><span class="line"><span class="keyword">assert</span> matrix3.size() == <span class="number">3</span></span><br><span class="line"></span><br><span class="line">Integer[][] matrix2 ②</span><br><span class="line">matrix2 = [[<span class="number">1</span>, <span class="number">2</span>], [<span class="number">3</span>, <span class="number">4</span>]]</span><br><span class="line"><span class="keyword">assert</span> matrix2 <span class="keyword">instanceof</span> Integer[][]</span><br></pre></td></tr></table></figure>
<p>① You can define the bounds of a new array</p>
<p>② Or declare an array without specifying its bounds</p>
<p>Access to elements of an array follows the same notation as for lists:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">String[] names = [<span class="string">'Cédric'</span>, <span class="string">'Guillaume'</span>, <span class="string">'Jochen'</span>, <span class="string">'Paul'</span>]</span><br><span class="line"><span class="keyword">assert</span> names[<span class="number">0</span>] == <span class="string">'Cédric'</span> ①</span><br><span class="line"></span><br><span class="line">names[<span class="number">2</span>] = <span class="string">'Blackdrag'</span> ②</span><br><span class="line"><span class="keyword">assert</span> names[<span class="number">2</span>] == <span class="string">'Blackdrag'</span></span><br></pre></td></tr></table></figure>
<p>① Retrieve the first element of the array</p>
<p>② Set the value of the third element of the array to a new value</p>
<p>Java’s array initializer notation is not supported by Groovy, as the curly braces can be misinterpreted with the notation of Groovy closures.</p>
<h2 id="Maps"><a href="#Maps" class="headerlink" title="Maps"></a>Maps</h2><p>Sometimes called dictionaries or associative arrays in other languages, Groovy features maps. Maps associate keys to values, separating keys and values with colons, and each key/value pairs with commas, and the whole keys and values surrounded by square brackets.</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> colors = [<span class="string">red:</span> <span class="string">'#FF0000'</span>, <span class="string">green:</span> <span class="string">'#00FF00'</span>, <span class="string">blue:</span> <span class="string">'#0000FF'</span>]①</span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> colors[<span class="string">'red'</span>] == <span class="string">'#FF0000'</span> ②</span><br><span class="line"><span class="keyword">assert</span> colors.green  == <span class="string">'#00FF00'</span> ③</span><br><span class="line"></span><br><span class="line">colors[<span class="string">'pink'</span>] = <span class="string">'#FF00FF'</span> ④</span><br><span class="line">colors.yellow  = <span class="string">'#FFFF00'</span> ⑤</span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> colors.pink == <span class="string">'#FF00FF'</span></span><br><span class="line"><span class="keyword">assert</span> colors[<span class="string">'yellow'</span>] == <span class="string">'#FFFF00'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> colors <span class="keyword">instanceof</span> java.util.LinkedHashMap</span><br></pre></td></tr></table></figure>
<p>① We define a map of string color names, associated with their hexadecimal-coded html colors</p>
<p>② We use the subscript notation to check the content associated with the red key</p>
<p>③ We can also use the property notation to assert the color green’s hexadecimal representation</p>
<p>④ Similarly, we can use the subscript notation to add a new key/value pair</p>
<p>⑤ Or the property notation, to add the yellow color</p>
<p>When using names for the keys, we actually define string keys in the map.<br>Groovy creates maps that are actually instances of java.util.LinkedHashMap.</p>
<p>If you try to access a key which is not present in the map:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">assert</span> colors.unknown == <span class="literal">null</span></span><br></pre></td></tr></table></figure>
<p>You will retrieve a null result.</p>
<p>In the examples above, we used string keys, but you can also use values of other types as keys:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> numbers = [<span class="number">1</span>: <span class="string">'one'</span>, <span class="number">2</span>: <span class="string">'two'</span>]</span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> numbers[<span class="number">1</span>] == <span class="string">'one'</span></span><br></pre></td></tr></table></figure>
<p>Here, we used numbers as keys, as numbers can unambiguously be recognized as numbers, so Groovy will not create a string key like in our previous examples. But consider the case you want to pass a variable in lieu of the key, to have the value of that variable become the key:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> key = <span class="string">'name'</span></span><br><span class="line"><span class="keyword">def</span> person = [<span class="string">key:</span> <span class="string">'Guillaume'</span>] ①</span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> !person.containsKey(<span class="string">'name'</span>) ②</span><br><span class="line"><span class="keyword">assert</span> person.containsKey(<span class="string">'key'</span>) ③</span><br></pre></td></tr></table></figure>
<p>① The key associated with the ‘Guillaume’ name will actually be the “key” string, not the value associated with the key variable</p>
<p>② The map doesn’t contain the ‘name’ key</p>
<p>③Instead, the map contains a ‘key’ key</p>
<p>You can also pass quoted strings as well as keys: [“name”: “Guillaume”]. This is mandatory if your key string isn’t a valid identifier, for example if you wanted to create a string key containing a hash like in: [“street-name”: “Main street”].</p>
<p>When you need to pass variable values as keys in your map definitions, you must surround the variable or expression with parentheses:</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">person = [(key): <span class="string">'Guillaume'</span>] ①</span><br><span class="line"></span><br><span class="line"><span class="keyword">assert</span> person.containsKey(<span class="string">'name'</span>) ②</span><br><span class="line"><span class="keyword">assert</span> !person.containsKey(<span class="string">'key'</span>) ③</span><br></pre></td></tr></table></figure>
<p>① This time, we surround the key variable with parentheses, to instruct the parser we are passing a variable rather than defining a string key</p>
<p>② The map does contain the name key</p>
<p>③ But the map doesn’t contain the key key as before</p>
<p>that’s all, thanks for your reading.</p>

      
    </div>
    
    
    

    

    
      <div>
        <div style="padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;">
  <div>============ END ============</div>
  <button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
    <span>打赏</span>
  </button>
  <div id="QR" style="display: none;">

    
      <div id="wechat" style="display: inline-block">
        <img id="wechat_qr" src="/images/wechatpay.png" alt="段燚涛 微信支付">
        <p>微信支付</p>
      </div>
    

    
      <div id="alipay" style="display: inline-block">
        <img id="alipay_qr" src="/images/alipay.png" alt="段燚涛 支付宝">
        <p>支付宝</p>
      </div>
    

    

  </div>
</div>

      </div>
    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/Groovy/" rel="tag"># Groovy</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2019/04/22/译-高级-DataBinding-绑定到-LiveData-单向绑定-双向绑定/" rel="next" title="[译] 高级 DataBinding: 绑定到 LiveData (单向绑定 & 双向绑定) ">
                <i class="fa fa-chevron-left"></i> [译] 高级 DataBinding: 绑定到 LiveData (单向绑定 & 双向绑定) 
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2019/04/25/Koin-with-ViewModel/" rel="prev" title="Koin with ViewModel">
                Koin with ViewModel <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  
    <div class="comments" id="comments">
      <div id="lv-container" data-id="city" data-uid="MTAyMC80MzUzNC8yMDA3Mw=="></div>
    </div>

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image" src="/images/avatar.jpeg" alt="段燚涛">
            
              <p class="site-author-name" itemprop="name">段燚涛</p>
              <p class="site-description motion-element" itemprop="description"></p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/archives/">
              
                  <span class="site-state-item-count">19</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/categories/index.html">
                  <span class="site-state-item-count">6</span>
                  <span class="site-state-item-name">分类</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                <a href="/tags/index.html">
                  <span class="site-state-item-count">17</span>
                  <span class="site-state-item-name">标签</span>
                </a>
              </div>
            

          </nav>

          
            <div class="feed-link motion-element">
              <a href="/atom.xml" rel="alternate">
                <i class="fa fa-rss"></i>
                RSS
              </a>
            </div>
          

          
            <div class="links-of-author motion-element">
                
                  <span class="links-of-author-item">
                    <a href="https://github.com/duanyitao" target="_blank" title="GitHub">
                      
                        <i class="fa fa-fw fa-github"></i>GitHub</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="mailto:duanyitao7937@gmail.com" target="_blank" title="E-Mail">
                      
                        <i class="fa fa-fw fa-envelope"></i>E-Mail</a>
                  </span>
                
            </div>
          

          
          

          
          
            <div class="links-of-blogroll motion-element links-of-blogroll-inline">
              <div class="links-of-blogroll-title">
                <i class="fa  fa-fw fa-link"></i>
                快速链接
              </div>
              <ul class="links-of-blogroll-list">
                
                  <li class="links-of-blogroll-item">
                    <a href="https://github.com/googlesamples/android-architecture/tree/todo-mvvm-databinding/todoapp" title="Android-architecture" target="_blank">Android-architecture</a>
                  </li>
                
                  <li class="links-of-blogroll-item">
                    <a href="https://developer.android.google.cn/jetpack" title="Jetpack" target="_blank">Jetpack</a>
                  </li>
                
              </ul>
            </div>
          

          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#Comments"><span class="nav-number">1.</span> <span class="nav-text">Comments</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Single-line-comment"><span class="nav-number">1.1.</span> <span class="nav-text">Single line comment</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Multiline-comment"><span class="nav-number">1.2.</span> <span class="nav-text">Multiline comment</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#GroovyDoc-comment"><span class="nav-number">1.3.</span> <span class="nav-text">GroovyDoc comment</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Shebang-line"><span class="nav-number">1.4.</span> <span class="nav-text">Shebang line</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Keywords"><span class="nav-number">2.</span> <span class="nav-text">Keywords</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Identifiers"><span class="nav-number">3.</span> <span class="nav-text">Identifiers</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Normal-identifiers"><span class="nav-number">3.1.</span> <span class="nav-text">Normal identifiers</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Quoted-identifiers"><span class="nav-number">3.2.</span> <span class="nav-text">Quoted identifiers</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Strings"><span class="nav-number">4.</span> <span class="nav-text">Strings</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Single-quoted-string"><span class="nav-number">4.1.</span> <span class="nav-text">Single quoted string</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#String-concatenation"><span class="nav-number">4.2.</span> <span class="nav-text">String concatenation</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Triple-single-quoted-string"><span class="nav-number">4.3.</span> <span class="nav-text">Triple single quoted string</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Escaping-special-characters"><span class="nav-number">4.4.</span> <span class="nav-text">Escaping special characters</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Unicode-escape-sequence"><span class="nav-number">4.5.</span> <span class="nav-text">Unicode escape sequence</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Double-quoted-string"><span class="nav-number">4.6.</span> <span class="nav-text">Double quoted string</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#String-interpolation"><span class="nav-number">4.7.</span> <span class="nav-text">String interpolation</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Special-case-of-interpolating-closure-expressions"><span class="nav-number">4.8.</span> <span class="nav-text">Special case of interpolating closure expressions</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Interoperability-with-Java"><span class="nav-number">4.9.</span> <span class="nav-text">Interoperability with Java</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#GString-and-String-hashCodes"><span class="nav-number">4.10.</span> <span class="nav-text">GString and String hashCodes</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Triple-double-quoted-string"><span class="nav-number">4.11.</span> <span class="nav-text">Triple double quoted string</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Slashy-string"><span class="nav-number">4.12.</span> <span class="nav-text">Slashy string</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Dollar-slashy-string"><span class="nav-number">4.13.</span> <span class="nav-text">Dollar slashy string</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#String-summary-table"><span class="nav-number">4.14.</span> <span class="nav-text">String summary table</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Characters"><span class="nav-number">4.15.</span> <span class="nav-text">Characters</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Numbers"><span class="nav-number">5.</span> <span class="nav-text">Numbers</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Integral-literals"><span class="nav-number">5.1.</span> <span class="nav-text">Integral literals</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Alternative-non-base-10-representations"><span class="nav-number">5.1.1.</span> <span class="nav-text">Alternative non-base 10 representations</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#Binary-literal"><span class="nav-number">5.1.1.1.</span> <span class="nav-text">Binary literal</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#Octal-literal"><span class="nav-number">5.1.1.2.</span> <span class="nav-text">Octal literal</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#Hexadecimal-literal"><span class="nav-number">5.1.1.3.</span> <span class="nav-text">Hexadecimal literal</span></a></li></ol></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Decimal-literals"><span class="nav-number">5.2.</span> <span class="nav-text">Decimal literals</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Underscore-in-literals"><span class="nav-number">5.3.</span> <span class="nav-text">Underscore in literals</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Number-type-suffixes"><span class="nav-number">5.4.</span> <span class="nav-text">Number type suffixes</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Math-operations"><span class="nav-number">5.5.</span> <span class="nav-text">Math operations</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#The-case-of-the-division-operator"><span class="nav-number">5.5.1.</span> <span class="nav-text">The case of the division operator</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#The-case-of-the-power-operator"><span class="nav-number">5.5.2.</span> <span class="nav-text">The case of the power operator</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Booleans"><span class="nav-number">6.</span> <span class="nav-text">Booleans</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Lists"><span class="nav-number">7.</span> <span class="nav-text">Lists</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Arrays"><span class="nav-number">8.</span> <span class="nav-text">Arrays</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Maps"><span class="nav-number">9.</span> <span class="nav-text">Maps</span></a></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      
        <div class="back-to-top">
          <i class="fa fa-arrow-up"></i>
          
            <span id="scrollpercent"><span>0</span>%</span>
          
        </div>
      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Build by duanyitao.</span>

  
    <span class="post-meta-divider">|</span>
    <span class="post-meta-item-icon">
      <i class="fa fa-area-chart"></i>
    </span>
    
      <span class="post-meta-item-text">Site words total count&#58;</span>
    
    <span title="Site words total count">38.6k</span>
  
</div>









        







        
      </div>
    </footer>

    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  


  











  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  

  
  
    <script type="text/javascript" src="/lib/canvas-nest/canvas-nest.min.js"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.4"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  
    <script type="text/javascript">
      (function(d, s) {
        var j, e = d.getElementsByTagName(s)[0];
        if (typeof LivereTower === 'function') { return; }
        j = d.createElement(s);
        j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
        j.async = true;
        e.parentNode.insertBefore(j, e);
      })(document, 'script');
    </script>
  












  





  

  

  

  
  

  
  


  
  <script type="text/javascript" src="/js/src/js.cookie.js?v=5.1.4"></script>
  <script type="text/javascript" src="/js/src/scroll-cookie.js?v=5.1.4"></script>


  
  <script type="text/javascript" src="/js/src/exturl.js?v=5.1.4"></script>


</body>
</html>
